package vn.cuhanh.adapter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;
import java.util.Stack;

import vn.cuhanh.R;
import vn.cuhanh.bean.Banner;
import vn.cuhanh.bean.Game;
import vn.cuhanh.utils.HelperFunc;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class EfficientAdapter extends BaseAdapter {
	public interface IOnRowClickedCallback {
		public void onRowClicked(Object obj);
	}

	protected IOnRowClickedCallback onRowClickedCallback;

	public void setOnRowClickedCallback(IOnRowClickedCallback c) {
		this.onRowClickedCallback = c;
	}

	// base property
	private static String[] listFile; // list file trong sdcard
	public static HashMap<String, String> localImgMap; // map [id_tenGame] ->
														// [time] + index
														// trong listFile;
	private static String extStorageDirectory; // "sdcard cache folder/"
	private static SimpleDateFormat df;

	public static final int LARGE_SCREEN = 2;
	public static final int NORMAL_SCREEN = 1;
	public static final int SMALL_SCREEN = 0;
	// chua dung protected ListView lv;
	protected static Stack<Game> stackImg;
	// protected static HashMap<String, Bitmap> imageMap; // map [id] -> hinh
	public static HashMap<String, String> imageMap;
	public static Set<String> downloadingGameImg;
	protected LayoutInflater mInflater;
	public static Context context;
	protected ArrayList<Banner> topBannersUrl;
	public static float curScale = (float) 0.875;
	public static int screenSize = 0;

	public EfficientAdapter(Context context) {
		if (localImgMap == null)
			localImgMap = new HashMap<String, String>();
		if (stackImg == null)
			stackImg = new Stack<Game>();
		if (imageMap == null)
			imageMap = new HashMap<String, String>();

		df = new SimpleDateFormat(context.getResources().getString(
				R.string.simpleDateFormat));
		extStorageDirectory = Environment.getExternalStorageDirectory()
				.toString()
				+ context.getResources().getString(R.string.imgCacheFolder);
		File dir = new File(extStorageDirectory);
		if (!dir.exists()) {
			dir.mkdirs();
			listFile = null;
		} else {
			listFile = dir.list();
			for (int i = 0; i < listFile.length; i++) {
				String fileName = listFile[i];
				// Date time = new Date(0);
				String index = "";
				String t = "";
				if (fileName.length() >= 14) {
					index = fileName.substring(14);
					t = fileName.substring(0, 14) + i;
					if (localImgMap != null) {
						synchronized (localImgMap) {
							localImgMap.put(index, t);
						}
					}
				}

				/*
				 * try { time.setTime(df.parse(t).getTime()); } catch
				 * (ParseException e) { e.printStackTrace(); }
				 */

			}
		}

		// Cache the LayoutInflate to avoid asking for a new one each time.
		mInflater = LayoutInflater.from(context);
		EfficientAdapter.context = context;
	}

	public void getScale() {
		if (screenSize == 1 || screenSize == 2) {
			curScale = 1;
		}
	}


	// protected void ShowGameDetail(long id, int currTabIndex){
	// ZinggameActivity.tabsMngr.getTabHost().setCurrentTab(ZinggameActivity.TAB_GAMEDETAIL_INDEX);
	// ZinggameActivity.setForcus(currTabIndex);
	// ((GameDetailActivity) GameDetailActivity.ctx).loadDetail(id);
	// }

	/*
	 * neu co hinh tren sdcard - return index trong listFile - set outDate =
	 * time hinh do dc save vao sdcard else - return -1 - outDate = null
	 */
	private static int localImgTime(String name, Date outDate) {
		String fileName = name + ".png";
		if (listFile != null) {
			if (localImgMap.containsKey(fileName)) {
				String val = localImgMap.get(fileName);
				String timeStr = val.substring(0, 14);
				try {
					if (outDate != null) {
						outDate.setTime(df.parse(timeStr).getTime());
					}
					return Integer.parseInt(val.substring(14));
				} catch (ParseException e) {
					HelperFunc.readStackTrace(e);
				}
			}
		}
		return -1;
	}

	/*
	 * lastUpdateTime phai khac null
	 * 
	 * neu hinh trong sdcard moi hon lastUpdateTime - return tenFile png else -
	 * return null
	 */
	private static String getLocalImgFileName(String fileName,
			Date lastUpdateTime) {
		if (lastUpdateTime == null)
			return null;
		Date localTime = new Date(0);
		int index = localImgTime(fileName, localTime);
		if (index == -1)
			return null;

		if (localTime.compareTo(lastUpdateTime) > 0)
			return listFile[index];
		else {
			// no need ______delete old file, update list file ,
			// String filePath = extStorageDirectory + listFile[index];
			// File f = new File(filePath);
			// if (f.exists()){
			// Log.v("_________delete __________",f.getAbsolutePath());
			// f.delete();
			//
			// }
			return null;
		}
	}

	/*
	 * input url return drawable neu input them path thi se save vao sdcard
	 */
	private static Drawable downloadImg(String url, String saveToFileName) {
		Drawable d = null;
		InputStream is = null;
		FileOutputStream outStream = null;
		try {

			is = (InputStream) new URL(url).getContent();
			d = Drawable.createFromStream(is, "");
			if (saveToFileName != null && d != null) {
				File file = new File(saveToFileName);
				Bitmap bm = ((BitmapDrawable) d).getBitmap();
				outStream = new FileOutputStream(file);
				bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
				outStream.flush();
				// outStream.close();
			}
		} catch (FileNotFoundException e) {
			HelperFunc.readStackTrace(e);
		} catch (MalformedURLException e) {
			HelperFunc.readStackTrace(e);
			// Log.v("error",e.toString());
		} catch (IOException e) {
			// Log.v("error",e.toString());
			HelperFunc.readStackTrace(e);
		} catch (java.lang.OutOfMemoryError e) {
			/*
			 * ((Activity) context).runOnUiThread(new Runnable() {
			 * 
			 * @Override public void run() { Toast.makeText(context,
			 * "Máy không đủ bộ nhớ", Toast.LENGTH_SHORT).show(); } });
			 */

			// System.gc();
			HelperFunc.readStackTrace(e);
			((Activity) context).finish();
		}

		finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					HelperFunc.readStackTrace(e);
				}
			}
			if (outStream != null) {
				try {
					outStream.close();
				} catch (IOException e) {
					HelperFunc.readStackTrace(e);
				}
			}
		}
		return d;
	}

	/*
	 * Goi ham nay de load hinh tu sv cho game input: - url - id_tenGame -
	 * lastUpdate [= null -> k check lastUpdate]
	 */
	public static Drawable loadImageFromWebOperations(String url, String fileName, Date lastestUpdate) {
		try {
			Drawable d;
			if (lastestUpdate == null) {
				return d = downloadImg(url, fileName);
			}

			String filePath = getLocalImgFileName(fileName, lastestUpdate);

			if (filePath == null) {
				filePath = extStorageDirectory + (df.format(new Date()))
						+ fileName + ".png";
				d = downloadImg(url, filePath);
			} else {
				filePath = extStorageDirectory + filePath;
				Bitmap bm = decodeFile(filePath);
				if (bm != null) {
					d = new BitmapDrawable(bm);
				} else {
					d = downloadImg(url, filePath);
				}
			}
			return d;
		} catch (Exception e) {
			HelperFunc.readStackTrace(e);
			return null;
		} catch (java.lang.OutOfMemoryError e) {
			HelperFunc.readStackTrace(e);
			return null;
		}
	}

	// return String
	public static String loadImageFromWeb(String url, String fileName,
			Date lastestUpdate) {
		try {
			String filePath = getLocalImgFileName(fileName, lastestUpdate);

			if (filePath == null) {
				filePath = extStorageDirectory + (df.format(new Date()))
						+ fileName + ".png";
				downloadImg(url, filePath);
				return filePath;
			} else {
				filePath = extStorageDirectory + filePath;
				return filePath;
				// Bitmap bm = BitmapFactory.decodeFile(filePath);
				// if (bm != null) {
				// d = new BitmapDrawable(bm);
				// } else {
				// d = downloadImg(url, filePath);
				// }
			}
		} catch (Exception e) {
			HelperFunc.readStackTrace(e);
			return null;
		} catch (java.lang.OutOfMemoryError e) {
			HelperFunc.readStackTrace(e);
			return null;
		}
	}

//	public static class ImgLoaderMngr implements Runnable {
//		private Context ctx;
//
//		public ImgLoaderMngr(Context ctx) {
//			this.ctx = ctx;
//
//		}
//
//		public void run() {
//			// Log.v("+++CHG started THREAD ",this.toString());
//			numThreadAlive = 0;
//			try {
//				while (true) {
//
//					if (stackImg.size() == 0) {
//						synchronized (stackImg) {
//							stackImg.wait();
//						}
//					}
//
//					if (stackImg.size() != 0) {
//						Game g;
//						synchronized (stackImg) {
//							g = stackImg.pop();
//						}
//						numLoaded++;
//						while (numThreadAlive >= maxDownloadImgConnection) {
//							Thread.sleep(100);
//						}
//						numThreadAlive++;
//						(new LoadImg(ctx, g)).start();
//					}
//
//					if (Thread.interrupted()) {
//						break;
//					}
//				}
//			} catch (InterruptedException e) {
//				HelperFunc.readStackTrace(e);
//			} catch (EmptyStackException e) {
//			} catch (java.lang.OutOfMemoryError e) {
//				((Activity) context).finish();
//			}
//			// Log.v("+++CHG end THREAD ",this.toString());
//		}
//	}

	/*
	 * adapter call ham nay de load hinh cho game, nho set imgView cho GameObj
	 */
//	protected void showImgIconGame(Game g) {
//		try {
//			if (!MainActivity.isOnline) {
//
//				try {
//					String cacheFile = String.format("%s_%s", g.info.id,
//							g.info.name.replaceAll("[^a-zA-Z0-9]+", ""));
//
//					File file = new File(cacheFile);
//
//					int index = localImgTime(cacheFile, null);
//					if (index != -1) {
//						cacheFile = extStorageDirectory + listFile[index];
//						Bitmap bm = decodeFile(cacheFile);
//
//						g.getImgV().setImageBitmap(
//								Bitmap.createScaledBitmap(bm, 70, 70, false));
//
//					} else {
//						g.getImgV().setImageResource(R.drawable.icon);
//					}
//				} catch (java.lang.OutOfMemoryError e) {
//					((Activity) context).finish();
//					HelperFunc.readStackTrace(e);
//				}
//				return;
//			}
//
//			if (imageMap.containsKey(g.info.id)) {
//				String filePath = imageMap.get(g.info.id);
//				Bitmap bm = decodeFile(filePath);
//
//				if (bm != null) {
//					int bmpWidth = bm.getWidth();
//					int bmpHeight = bm.getHeight();
//					Matrix matrix = new Matrix();
//					matrix.postScale(curScale, curScale);
//					Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0,
//							bmpWidth, bmpHeight, matrix, true);
//					g.getImgV().setImageBitmap(resizedBitmap);
//
//				}
//			} else {
//				synchronized (stackImg) {
//					stackImg.push(g);
//					stackImg.notifyAll();
//				}
//				// Start thread if it's not started yet
//				if (imgLoaderMngrThead.getState() == Thread.State.NEW)
//					imgLoaderMngrThead.start();
//
//				if (imgLoaderMngrThead.getState() == Thread.State.TERMINATED) {
//
//					imgLoaderMngrThead = new Thread(new ImgLoaderMngr(context));
//					imgLoaderMngrThead.start();
//				}
//				g.getImgV().setImageResource(R.drawable.app_bg);
//			}
//		} catch (java.lang.OutOfMemoryError e) {
//			HelperFunc.readStackTrace(e);
//		}
//	}

	public static Bitmap decodeFile(String path) {
		Bitmap b = null;
		try {
			// Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inPurgeable = true; // Tell to gc that whether it needs free
									// memory, the Bitmap can be cleared
			o.inInputShareable = true;
			o.inJustDecodeBounds = true;

			File f = new File(path);
			FileInputStream fis = new FileInputStream(f);

			// BitmapFactory.decodeStream(fis, null, o);
			BitmapFactory.decodeFileDescriptor(fis.getFD(), null, o);
			fis.close();
			int IMAGE_MAX_SIZE = 800;
//			 if (screenSize == SMALL_SCREEN) {
//			 IMAGE_MAX_SIZE = 200;
//			 } else if (screenSize == NORMAL_SCREEN) {
//			 IMAGE_MAX_SIZE = 400;
//			 } else {
//			 IMAGE_MAX_SIZE = 800;
//			 }
			int scale = 1;
			if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
				scale = (int) Math.pow(
						2,
						(int) Math.round(Math.log(IMAGE_MAX_SIZE
								/ (double) Math.max(o.outHeight, o.outWidth))
								/ Math.log(0.5)));
			}

			// Decode with inSampleSize
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;
			o2.inScaled = false;
			fis = new FileInputStream(f);
			// b = BitmapFactory.decodeStream(fis, null, o2);
			b = BitmapFactory.decodeFileDescriptor(fis.getFD(), null, o2);
			fis.close();
		} catch (IOException e) {
		} catch (java.lang.OutOfMemoryError e) {
			((Activity) context).finish();
		}
		return b;
	}

	public long getItemId(int position) {
		return -1;
	}

	public int getCount() {
		return topBannersUrl.size();
	}

	public Object getItem(int position) {
		return topBannersUrl.get(position);
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		return null;
	}
}